#include "StdAfx.h"
#include "Route.h"

//===========================================================================
IRoute * CreateRoute(
    Piece piece /* = Piece::NONE */
) {
    return new Route( piece );
}

//===========================================================================
Route::Route( Piece piece = Piece::NONE )
    : m_piece( piece )
{
}

//===========================================================================
Route::~Route( void )
{
    this->Cleanup();
}

//===========================================================================
void Route::Release( void )
{
    Route::Release( this );
}

//===========================================================================
void Route::Release( Route * route )
{
    if( route )
        delete route;
}

//===========================================================================
Piece Route::GetPiece( void ) const
{
    return this->m_piece;
}

//===========================================================================
const vector< Position > & Route::GetRoute( void ) const
{
    return this->m_route;
}

//===========================================================================
const Position * Route::GetDestination( void ) const
{
    return this->GetMoveCount()
         ? &this->m_route.back()
         : NULL;
}

//===========================================================================
const Position * Route::GetAt(
    unsigned int index
) const {
    return index < this->m_route.size()
         ? &this->m_route[ index ]
         : NULL;
}

//===========================================================================
void Route::RewindLastMoves(
    unsigned int count
) {
    assert( count <= this->GetMoveCount() );

    for( unsigned int i = 0; i < count; i++ )
        this->m_route.pop_back();
}

//===========================================================================
IRoute * Route::Clone( void )
{
    IRoute * route = CreateRoute( this->m_piece );

    auto it    = this->m_route.begin();
    auto itEnd = this->m_route.end();
    for( ; it != itEnd; it++ )
        route->AppendMove( *it );
    
    return route;
}

//===========================================================================
void Route::Cleanup( void )
{
    this->m_route.clear();
}

//===========================================================================
unsigned int Route::GetMoveCount( void ) const
{
    return this->m_route.size();
}

//===========================================================================
void Route::AppendMove(
    const Position & position
) {
    this->m_route.push_back( position );
}

//===========================================================================
void Route::AppendMove(
    const IRoute * route
) {
    assert( route );

    unsigned int size = route->GetMoveCount();
    for( unsigned int i = 0; i < size; i++ )
        this->AppendMove( *route->GetAt( i ) );
}

//===========================================================================
bool Route::HasJumped( void ) const
{
    return this->GetMoveCount() > 2
         ? true
         : false;
}